/*
 * Copyright (c) 2010-2011 Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */
package jsr335.agent;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * @author Remi Forax
 */
public class ClassMirror {
  private final ArrayList<ClassMirror> supertypes =
      new ArrayList<ClassMirror>();
  
  private Map<String, MethodMirror> internalMethodMap;
  private Map<String, MethodMirror> exportedMethodMap;
  
  public ClassMirror() {
    // create an empty class mirror
  }
  
  void addSupertype(ClassMirror supertype) {
    supertypes.add(Objects.requireNonNull(supertype));
  }
  
  public boolean isSubtypeOf(ClassMirror type) {
    if (type == this)
      return true;
    for(ClassMirror supertype: supertypes) {
      if (supertype.isSubtypeOf(type)) {
        return true;
      }
    }
    return false;
  }
  
  public void importMethods(boolean isInterface, Map<String, MethodMirror> methodMap) {
    if (isInterface) {
      internalMethodMap = null;
      exportedMethodMap = Objects.requireNonNull(methodMap);
      return;
    }
    internalMethodMap = Objects.requireNonNull(methodMap);
    exportedMethodMap = export(methodMap);
  }
  
  private Map<String, MethodMirror> export(Map<String, MethodMirror> methodMap) {
    HashMap<String, MethodMirror> exported = new HashMap<String, MethodMirror>();
    for(Map.Entry<String, MethodMirror> entry: methodMap.entrySet()) {
      exported.put(entry.getKey(), entry.getValue().erase());
    }
    return exported;
  }

  public  Map<String, MethodMirror> getInternalMethodMap() {
    return internalMethodMap;
  }
  
  public  Map<String, MethodMirror> getExportedMethodMap() {
    return exportedMethodMap;
  }
}
